﻿$$.Pages = {};
$$.PageFactory = function (htmlsName) {
    var me = this;
    var emptyfunc = function () { };
    var homesNode = $("#AppHome");
    var pagesNode = $("#AppPages") || document.body || document.documentElement;

    me.GetQueryParams = function (hash) {
        var q = hash || location.hash;
        if (!q) return null;
        if (q.substr(0, 1) === "#") q = q.substr(1);
        if (!q) return null;
        var arr = q.split("&");
        if (!arr || arr.length < 1) return null;
        var data = {};
        var sidx = 0;
        var p = arr[0];
        if (p && p.length > 0 && p.indexOf("=") < 0) {
            var arr1 = p.split(".");
            if (arr1) {
                if (arr1[0]) data.Page = arr1[0].trim().toLowerCase();
                if (arr1[1]) data.Option = $$.ParseInt(arr1[1]);
            }
            sidx = 1;
        }
        var nm = null, ns = null;
        data.Params = {};
        for (var i = sidx; i < arr.length; i++) {
            var s = arr[i];
            if (!s) continue;
            var idx = s.indexOf("=");
            if (idx < 1 || idx >= s.length - 1) continue;
            var n = s.substr(0, idx).trim();
            if (!n) continue;
            var s = s.substr(idx + 1).trim();
            if (!s) continue;
            nm = n.toLowerCase();
            if (window.decodeURIComponent) ns = window.decodeURIComponent(s);
            else if (window.decodeURI) ns = window.decodeURI(s);
            else ns = s;
            data.Params[nm] = ns;
        }

		//处理最后一个参数可能在分享后被强行跟上其他参数
        if (ns) {
        	var idx0 = ns.indexOf("?");
        	var idx1 = ns.indexOf("#");
        	if (idx0 < 0 || (idx1 >= 0 && idx1 < idx0)) idx0 = idx1;
        	idx1 = ns.indexOf("&");
        	if (idx0 < 0 || (idx1 >= 0 && idx1 < idx0)) idx0 = idx1;
        	if (idx0 >= 0) {
        		ns = ns.substr(0, idx0);
        		data.Params[nm] = ns;
        	}
        }
        return data;
    };

    function getOption(num) {
        //运动效果,个十位，单选：1右方 2左方 3上方 4下方 99无，默认1
        //显示效果，十位以上，多选：1模糊，2弹出（被遮挡的页面不隐藏）,4关闭发起页面
    	if (!num) return { move: 1 };
        var type = $.type(num);
        if (type === "object") return num;
        if (type === "string") num = $$.ParseInt(num);
        if (!(num > 0)) return { move: 1 };
        var option = {};
        if (num >= 100) {
            var n = Math.floor(num / 100);
            if (n & 1) option.fuzzy = true;
            if (n & 2) option.pop = true;
            if (n & 4) option.close = true;
            num %= 100;
        }
        if (num > 0) {
            if (num === 99) option.move = 0;
            else option.move = num;
        }
        else option.move = 1;
        return option;
    }
    function getOptionClas(option) {
    	var clas = "";
    	if (option.move) clas = "move" + option.move;
    	if (option.fuzzy) {
    		if (clas) clas += " fuzzy";
    		else clas = "fuzzy";
    	}
    	return clas;
    }

    var handlers = {};
    for (var n in $$.Pages) {
    	handlers[n.toLowerCase()] = $$.Pages[n];
    }
    delete $$.Pages;

    var htmls = null;
    $$.Ajax((htmlsName ? htmlsName : "g") + ".html?" + $$.Version, function (text) {
    	var hs = {};
    	if (!text || text.length < 30) return;
    	var arr = text.match(/<body page=\"?\w+\"?>[\s\S]+?<\/body>/gi);
    	if (!arr || arr.length < 1) return;
    	for (var i = 0; i < arr.length; i++) {
    		var html = arr[i];
    		var ar = /<body page=\"?(\w+)\"?>\s*([\s\S]+?)\s*<\/body>/gi.exec(html);
    		if (!ar || ar.length < 3) continue;
    		hs[ar[1].toLowerCase()] = ar[2].trim();
    	}
    	htmls = hs;
    }, null, null, true, true);

    me.GetHtml = function (name, callback) {
    	if (!callback) return;
    	if (!name) { callback(); return; }
    	var n = 0; name = ("" + name).toLowerCase();
    	var t = setInterval(function () {
    		if (htmls) { clearInterval(t); callback(htmls[name]); }
    		else if (++n > 1000) { clearInterval(t); callback(); }
    	}, 15);
    };

    me.GetHandler = function (name) {
    	if (!name) return null;
    	name = ("" + name).toLowerCase();
        return handlers[name];
    };

	//todo:进度条会卡住
    var paging = 0;
    var pageArr = [];
    var pageCur = null;
    var pageZIndex = 1001;
    var presists = {};
    function get(name, params, callback, options) {
    	if (paging > 0) return null;
        var handle = me.GetHandler(name);
        if (!handle) return null;
        name = ("" + name).toLowerCase();

        var pidx = paging = ++pageZIndex;
        var handler = new handle(name, params, callback);
        handler.HName = name;
        if (handler.IsPresist === true) presists[name] = handler;
        options = getOption(options);

        function relax() { if (pidx === paging) paging = 0; };
        function dispose() {
            relax();
            if (!handler) return;
            if (handler.IsPresist === true) handler.Hide();
            else {
            	handler._Dispose();
            	handler = null;
            }
        };

        handler._Ready = function () {
        	if (!handler) return;
        	me.Disposed = false;
        	var jnode = $(handler.Node);
        	var clas = getOptionClas(options);
        	if (clas) jnode.addClass(clas);
        	if (handler.IsHome) jnode.appendTo(homesNode);
        	else jnode.appendTo(pagesNode);
        };
        handler._Render = function () {
        	if (!handler) return;
        	handler.Render();
        };
        handler._Enter = function () {
        	if (!handler) return;
        	handler.Node.style.zIndex = pidx;
        	var a = window.getComputedStyle(handler.Node).left;
        	var jnode = $(handler.Node);
        	if (options.fuzzy) {
        		jnode.removeClass("fuzzy");
        		delete options.fuzzy;
        	}
        	if (options.move) jnode.removeClass("move" + options.move);
        	if (handler.IsHome) {
        		$("#HomeMenu p.sel").removeClass("sel");
        		$("#HomeMenu p[data-href='" + handler.IsHome + ".99']").addClass("sel");
        	}

        	var p = pageCur;
        	pageCur = handler;
        	if (p) {
        		if (options.close === true || handler.IsHome) {
        			setTimeout(function () { relax(); p.Close(); }, 400);
        		}
        		else {
        			pageArr.push(p);
        			if (options.pop) setTimeout(relax, 300);
        			else setTimeout(function () { relax(); p.Hide(); }, 400);
        		}
        	}
        	else setTimeout(relax, 300);

        	if ($$.AppWeb === true) {
        		if (handler.HName === "shop_index") $$.DownAd.Show();
        		else $$.DownAd.Hide();
        	}
        };
        handler._Resume = function () {
        	if (!handler) return;
        	if (paging > 0 && paging !== pidx) return;
        	pidx = paging = ++pageZIndex;
        	handler.Node.style.display = "block";
        	handler._Enter();
        	handler.OnResume();
        	handler.RenderOk();
        	setTimeout(function () {
        		if (handler) handler.Node.getBoundingClientRect();
        	}, 600);
        };
        handler._Relax = relax;
        handler.Close = function () {
        	if (!handler || handler.Disposed || handler.OnClose() === false) return;
        	if (handler.IsPresist !== true) handler.Disposed = 1;
        	relax();
        	if (pageCur && handler !== pageCur) { dispose(); return; }
        	var p = pageArr.pop();
        	while (p && p.Disposed) {
        		p = pageArr.pop();
        	}
        	if (p) {
        		pageCur = p;
        		if (!options.pop) p.Show();
        		p.OnResume();
        		if ($$.AppWeb === true) {
        			if (p.HName === "shop_index") $$.DownAd.Show();
        			else $$.DownAd.Hide();
        		}
        	}
        	else if (!pageCur || pageCur === handler) {
        		pageCur = null;
        		me.OpenHome();
        	}
        	if (options.move) {
        		if (handler.Node) handler.Node.classList.add("move" + options.move);
        		setTimeout(dispose, 400);
        	}
        	else dispose();
        };

        return handler;
    }


    me.Relax = function () { paging = 0; };

	//name：页面名称（必须）
    //params：传递的参数，object类型
    //callback：回调函数，新开页面与发起页面通讯的方法
    //effect：过渡效果，int类型
	//close：true时，新开成功后，关闭发起页面，也可以把effect+400
	//除name外，参数在不需要时可以省略，但参数顺序要正确，如
    //$$.Page.Open(name, callback, close)，省略了params和effects
    me.Open = function (name, _params, _callback, _effect, _close) {
    	var params, callback, effect, close;
    	function ini(val, num) {
    		var tp = $.type(val);
    		if (tp === "object") {
    			if(params === undefined && num < 2) params = val;
    		}
    		else if (tp === "function") {
    			if (callback === undefined && num < 3) callback = val;
    		}
    		else if (tp === "number" && num < 4) {
    			if (effect === undefined && num < 4) effect = val;
    		}
    		else if (tp === "boolean") {
    			if (close === undefined) close = val;
    		}
    	}
    	ini(_params,1);
    	ini(_callback,2);
    	ini(_effect,3);
    	ini(_close,4);
    	return open(name, params, callback, effect, close);
    };
    function open(name, params, callback, effect, close) {
    	var page = presists[("" + name).toLowerCase()];
    	if (page && page.Disposed === false) {
    		if (paging > 0 || page === pageCur) return null;
    		page._Resume();
    		return page;
    	}

    	if (close === true) {
    		effect = getOption(effect);
    		effect.close = true;
    	}

    	page = get(name, params, callback, effect);
    	if (page) page.start();
    	return page;
    }

    me.OpenHref = function (hash, callback) {
        var data = me.GetQueryParams(hash);
        if (!data.Page || data.Page === "home") return;
        open(data.Page, data.Params, callback, data.Option);
    };

    var LastHash = location.hash;
	$(window).on("hashchange", function (evt) {
		var hash = location.hash;
		if (!hash || hash === LastHash) return;
		if (hash[0] === "~" || hash[1] === "~") return;
		LastHash = hash;
		me.OpenHref(hash);
    });

	me.OpenHome = function (params) {
		open("home_index", params, null, { fuzzy: true, move: 0 });
    };

	//打开店铺页面
	//检查外链情况
	//除id外，参数在不需要时可以省略，但参数顺序要正确，如
    me.OpenShop = function (id, params, callback, effect, close) {
    	id = $$.ParseInt(id) || 0;
    	if (id < 300000) return;
    	$$.GetSver(id, function (shop) {
    		if (!shop) return;
    		var svc = shop.Service;
    		if (!svc) return;
    		params.id = id;
    		if (svc.H5Url) {
    			params.src = svc.H5Url;
    		    //params.Force = "Force";
    			params.title = svc.Name;
    			me.Open("pub_viewlink", params, effect, close);
    			return;
    		}
    		me.Open("shop_index", params, callback, effect, close);
    	});
    };

	//关闭当前打开的页面
    me.CloseCur = function () {
    	var p = pageCur;
    	if (!p) {
    		var p = pageArr.pop();
    		if (!p) return false;
    		pageCur = p;
    	}
    	if (p.IsHome || pageArr.length < 1) return false;
    	p.Close();
    	return true;
    };

	//关闭当前打开的所有页面，然后打开home_index
    me.CloseAll = function () {
    	$("div.Page").remove();
    	paging = 0;
    	pageCur = null;
    	presists = {};
    	pageArr = [];
    	me.OpenHome();
    };
};